(ns sm-common.api
  (:require [org.zalando.stups.friboo.ring :refer :all]
            [org.zalando.stups.friboo.log :as log]
            [org.zalando.stups.friboo.config :refer [require-config]]
            [com.stuartsierra.component :as component]
            [ring.util.response :as r]
            [clj-time.core :as time]
            [buddy.hashers :as hs]
            [buddy.sign.jwt :as jwt]
            [buddy.core.hash :as hash]
            [sm-common.sql :as sql]))

(defrecord Controller [;; Set on creation
                       configuration
                       ;; Injected by the framework
                       db]
  component/Lifecycle
  (start [this]
    (log/info "启动安全鉴权服务")
    this)
  (stop [this]
    (log/info "停止安全鉴权服务")
    this))

(defn add-user
  [{:as this :keys [db configuration]} {:keys [user]} request]
  (let [pwd (hs/encrypt (:password user))]
    (log/info "add-user: %s" pwd)
    (r/response (sql/add-user! (update-in user [:password] #(hs/encrypt %)) {:connection db}))))

(defn get-users
  [{:as this :keys [db configuration]} params request]
  (log/info "get-users: %s" configuration)
  (r/response (sql/get-users {} {:connection db})))

(defn login-user
  [{:as this :keys [db configuration]} {:keys [username password]} request]
  (let [user (sql/get-user-by-username {:username username} {:connection db})]
    (log/info "login-user: %s" user)
    (if (empty? user)
      {:status 400 :body {:message "用户名错误"}}
      (if (hs/check password (:password (first user)))
        (if-let [exp (time/plus (time/now) (time/hours 12))]
          (r/response {:id (jwt/sign {:user (:name user) :exp exp} "key") :exp exp})
          {:status 400 :body {:message "密码错误"}})
        {:status 400 :body {:message "密码错误"}}))))

(defn logout-user
  [{:as this :keys [db configuration]} params request]
  (log/info "logout-user: %s" configuration)
  (r/response (sql/get-users {} {:connection db})))

(defn get-user-by-name
  [{:as this :keys [db configuration]} {:keys [username]} request]
  (log/info "get-user-by-name: %s" (sql/get-user-by-username {:username username} {:connection db}))
  (r/response (first (sql/get-user-by-username {:username username} {:connection db}))))

(defn update-user
  [{:as this :keys [db configuration]} {:keys [username user]} request]
  (log/info "update-user: %s username: %s" user username)
  (if (empty? (sql/get-user-by-username {:username username} {:connection db}))
    (r/response {:status 400 :body {:message "用户不存在"}})
    (do
      (if (= 1 (sql/update-user! user {:connection db}))
        (r/response user)
        (r/response {:status 400 :body {:message "未知错误"}})))))

(defn delete-user-by-name
  [{:as this :keys [db configuration]} {:keys [username]} request]
  (log/info "delete-user-by-name: %s" username)
  (r/response (sql/delete-user-by-name! {:username username} {:connection db})))

(defn add-role
  [{:as this :keys [db configuration]} {:keys [role]} request]
  (log/info "update-role: %s" role)
  (r/response (sql/add-role! role {:connection db})))

(defn get-roles
  [{:as this :keys [db configuration]} params request]
  (log/info "get-roles: %s" params)
  (r/response (sql/get-roles {} {:connection db})))

(defn get-role-by-id
  [{:as this :keys [db configuration]} {:keys [rid]} request]
  (log/info "get-roles: %s" rid)
  (r/response (sql/get-role-by-id {:id rid} {:connection db})))

(defn update-role
  [{:as this :keys [db configuration]} {:keys [role]} request]
  (log/info "update-role: %s" role)
  (r/response (sql/update-role! role {:connection db})))

(defn delete-role-by-id
  [{:as this :keys [db configuration]} {:keys [rid]} request]
  (log/info "delete-role-by-id: %s" rid)
  (r/response (sql/delete-role-by-id! {:id rid} {:connection db})))

(defn add-permission
  [{:as this :keys [db configuration]} {:keys [permission]} request]
  (log/info "update-role: %s" permission)
  (r/response (sql/add-permission! permission {:connection db})))

(defn get-permissions
  [{:as this :keys [db configuration]} params request]
  (log/info "get-permissions: %s" configuration)
  (r/response (sql/get-permissions {} {:connection db})))

(defn get-permission-by-id
  [{:as this :keys [db configuration]} {:keys [pid]} request]
  (log/info "get-permission-by-id: %s" pid)
  (r/response (sql/get-permission-by-id {:id pid} {:connection db})))

(defn update-permission
  [{:as this :keys [db configuration]} {:keys [permission]} request]
  (log/info "update-permission: %s" permission)
  (r/response (sql/update-permission! permission {:connection db})))

(defn delete-permission-by-id
  [{:as this :keys [db configuration]} {:keys [pid]} request]
  (log/info "delete-permission-by-id: %s" pid)
  (r/response (sql/delete-permission-by-id! {:id pid} {:connection db})))

;;(empty? (sql/get-user-by-username (:username user) {:connection db}))
(defn- check-users
  [users db]
  (let [result []]
    (log/info "users %s" users)
    (for [user users :while (not= 0 (count (sql/get-user-by-username {:username (:username user)} {:connection db})))]
      user)))

(defn add-group
  [{:as this :keys [db configuration]} {:keys [group]} request]
  (log/info "add-group: %s" group)
  (let [users (:users group)]
    (if (empty? users)
      (r/response (sql/add-group<! group {:connection db}))
      (do
        (log/info "check user: %s" (check-users users db))
        (if-let [vaild-users (check-users users db)]
          (if (= users vaild-users)
            (doseq [user vaild-users] (sql/insert-group-users! {:uid (:id user) :gid (:id group)} {:connection db}))))
        (if-let [grp (sql/add-group<! group {:connection db})]
          (do
            (log/info "grp: %s id: %s" grp (vals grp))
            (r/response (sql/get-group-by-id {:id (vals grp)} {:connection db})))
          (r/response {:status 400 :body {:message "error"}}))))))

(defn get-groups
  [{:as this :keys [db configuration]} params request]
  (log/info "get-groups: %s" configuration)
  (r/response (sql/get-groups {} {:connection db})))

(defn get-group-by-id
  [{:as this :keys [db configuration]} {:keys [gid]} request]
  (log/info "get-group-by-id: %s" gid)
  (r/response (sql/get-group-by-id {:id gid} {:connection db})))

(defn update-group
  [{:as this :keys [db configuration]} {:keys [group]} request]
  (log/info "update-group: %s" group)
  (r/response (sql/update-group! group {:connection db})))

(defn delete-group-by-id
  [{:as this :keys [db configuration]} {:keys [gid]} request]
  (log/info "delete-group-by-id: %s" gid)
  (r/response (sql/delete-group-by-id! {:id gid} {:connection db})))

(defn authorization
  [{:as this :keys [db configuration]} {:keys [auth]} request]
  (log/info "authorization: %s" auth)
  (r/response (sql/get-users {} {:connection db})))